Android开发高手课 【第三节】 课后作业解析 —— 内存优化
本节主要是讲了内存优化相关的工作,其中比较重要的是内存分配日志的获取,也就是demo中的部分。项目中主要讲了使用一些Hook框架,Hook分配对象时候的 RecordAllocation
方法,在分配对象的时候,计算对象的大小以及分配的对象类名。
Demo首先给分配对象的方法Hook了一个最大值,当超过最大值的时候,就将内存分配dump到本地:
1 | tracker.initForArt(BuildConfig.VERSION_CODE, 5000);//从 start 开始触发到5000的数据就 dump 到文件中 |
上面的函数就是将分配对象的最大值设置为5000,当分配对象的数量大于5000的时候,就会讲内存分配的日志dump到本地。
当分配对象达到5000的时候,LogCat会输出如下语句:
1 | 09-27 14:05:44.554 12228-12228/com.dodola.alloctrack I/AllocTracker: artGetRecentAllocations finished |
表示 /storage/emulated/0/crashDump/1569564344
就是已经dump下来的日志分配文件了。
接下来使用DumpPrinter,将日志文件解析出来(首先要将日志文件 adb pull
出来:
1 | java -jar tools/DumpPrinter-1.0.jar 1569564345 > dumpLog.txt |
打开之后就可以看到分配对象的内容了:
1 | Found 988 records: |
这里和使用Android Studio 自带的profile分析的内存是一样的。
接着看一下Hook的native方法的实现:
1 | void hookFunc() { |
可以看到针对SDK版本22、23、24、26都有不同的实现,但实际上如果通过函数的地址解析到方法,都是RecordAllocation这个方法,只是在由于在不同的SDK版本上实现不同,所以有了不同的hook。
在Hook了原始的RecordAllocation方法之后,调 MSHookFunction(hookRecordAllocation26, (void *) &newArtRecordAllocation26, (void **) &oldArtRecordAllocation26);
将其替换为 newArtRecordAllocation26
,最终实现如下:
1 | static bool newArtRecordAllocationDoing24(void *_this, Class *type, size_t byte_count) { |
由这章内容可以看出,如果要自定义内存的捕捉、自动化获取,需要对Art / Dalvik 虚拟机有很深入的了解,对于其一些native方法也要掌握。之后要加强在这方面的学习,再遇到问题的时候才能全面的,彻底的分析,解决。
本节demo在【华为 荣耀 V9 Android P】以及 【模拟器:Nexus 6 Android 7.0】上都无效果。换成了 【模拟器: Nexus 4 Android 6.0】才可以正常输出。